package com.moyu.admin.shiro;

import com.moyu.admin.service.ISysPermissionService;
import com.moyu.admin.service.ISysRoleService;
import com.moyu.admin.service.ISysUserLoginService;
import com.moyu.data.domain.SysPermission;
import com.moyu.data.domain.SysRole;
import com.moyu.data.domain.SysUserLogin;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

@Slf4j
public class MyRealm extends AuthorizingRealm {

  @Autowired private ISysUserLoginService sysUserService;

  @Autowired private ISysRoleService sysRoleService;

  @Autowired private ISysPermissionService sysPermissionService;

  {
    HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
    matcher.setHashAlgorithmName(Md5Hash.ALGORITHM_NAME);
    matcher.setHashIterations(2);
    matcher.setStoredCredentialsHexEncoded(true);
    this.setCredentialsMatcher(matcher);
  }

  @Override
  protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    String name = (String) principals.getPrimaryPrincipal();
    SysUserLogin user = sysUserService.findByName(name);
    log.info("==============>>>>>>>>>>>>>>>>>>>> 调用鉴权方法：doGetAuthorizationInfo");
    SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
    List<SysRole> roles = sysRoleService.findRolesByUser(user.getId());
    roles.stream().forEach(role -> info.addRole(role.getRole()));

    List<SysPermission> permissions = sysPermissionService.findPermissionsByRoles(roles);
    permissions
        .stream()
        .forEach(permission -> info.addStringPermission(permission.getPermission()));
    return info;
  }

  @Override
  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
      throws AuthenticationException {
    if (token.getPrincipal() == null) {
      return null;
    }
    String name = token.getPrincipal().toString();
    SysUserLogin user = sysUserService.findByName(name);
    if (user == null) {
      return null;
    } else {
      SimpleAuthenticationInfo info =
          new SimpleAuthenticationInfo(
              name,
              user.getPassword(),
              ByteSource.Util.bytes(user.getUsername() + user.getSalt()),
              getName());
      return info;
    }
  }
}
